﻿using StackExchange.Redis;
using System.Collections.Generic;

namespace NDK.Utils.Redis
{
    public static class RedisUtils
    {
        private static readonly ConfigurationOptions ConfigurationOptions = ConfigurationOptions.Parse("127.0.0.1:6379");
        private static readonly object Locker = new object();
        private static ConnectionMultiplexer _redisConn;

        /// <summary>
        /// 单例获取
        /// </summary>
        public static ConnectionMultiplexer RedisConn
        {
            get
            {
                if (_redisConn == null)
                {
                    lock (Locker)
                    {
                        if (_redisConn == null || !_redisConn.IsConnected)
                        {
                            _redisConn = ConnectionMultiplexer.Connect(ConfigurationOptions);
                        }
                    }
                }
                return _redisConn;
            }
        }
        public static IDatabase GetDatabase(int db = 0)
        {
            return RedisConn.GetDatabase(db);
        }
        /// <summary>
        /// 删除指定key
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool Delete(RedisKey key)
        {
            return GetDatabase().KeyDelete(key);
        }

        #region 字符串的读写删除
        /// <summary>
        /// 写入字符串value到key
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool WriteString(RedisKey key, RedisValue value)
        {
            return GetDatabase().StringSet(key, value);
        }
        /// <summary>
        /// 同时写入多个键值对
        /// </summary>
        /// <param name="keyValuePairs"></param>
        /// <returns></returns>
        public static bool WriteString(List<KeyValuePair<RedisKey, RedisValue>> keyValuePairs)
        {
            return GetDatabase().StringSet(keyValuePairs.ToArray());
        }
        /// <summary>
        /// 读取key对应的字符串value
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string ReadString(RedisKey key)
        {
            return GetDatabase().StringGet(key);
        }
        #endregion


        public static bool WriteHashSet(RedisKey key, RedisValue name, RedisValue value)
        {
            return GetDatabase().HashSet(key, name, value);
        }

        public static void WriteHashSet(RedisKey key, List<HashEntry> hashEntries)
        {
            GetDatabase().HashSet(key, hashEntries.ToArray());
        }
        /// <summary>
        /// 读取hash集合中指定字段名称的值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static RedisValue ReadHashSet(RedisKey key, RedisValue name)
        {
            return GetDatabase().HashGet(key, name);
        }
        /// <summary>
        /// 同时读取hash集合中,多个指定字段名称的值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="names"></param>
        /// <returns></returns>
        public static RedisValue[] ReadHashSet(RedisKey key, List<RedisValue> names)
        {
            return GetDatabase().HashGet(key, names.ToArray());
        }
        /// <summary>
        /// 读取hash集合中,所有字段的值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static RedisValue[] ReadHashSet(RedisKey key)
        {
            return GetDatabase().HashValues(key);
        }
        /// <summary>
        /// 读取hash集合中,所有的字段名
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static RedisValue[] ReadHashSetAllFiledNames(RedisKey key)
        {
            return GetDatabase().HashKeys(key);
        }
        /// <summary>
        /// 同时删除hash集合中，多个字段
        /// </summary>
        /// <param name="key">hash表的key</param>
        /// <param name="names">hash表中字段名称</param>
        /// <returns>删除的个数</returns>
        public static long DeleteHashSetFileds(RedisKey key, List<RedisValue> names)
        {
            return GetDatabase().HashDelete(key, names.ToArray());
        }
        /// <summary>
        /// 删除hash集合中，指定字段
        /// </summary>
        /// <param name="key"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static bool DeleteHashSetValue(RedisKey key, RedisValue name)
        {
            return GetDatabase().HashDelete(key, name);
        }


        /// <summary>
        /// 写一个值到集合中
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool WriteSet(RedisKey key, RedisValue value)
        {
            return GetDatabase().SetAdd(key, value);
        }
        /// <summary>
        /// 写一个值到有序集合中，根据值的分数大小排序
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="score"></param>
        /// <returns></returns>
        public static bool WriteSortedSet(RedisKey key, RedisValue value, double score)
        {
            return GetDatabase().SortedSetAdd(key, value, score);
        }
        /// <summary>
        /// 写多个值到集合中
        /// </summary>
        /// <param name="key"></param>
        /// <param name="values"></param>
        /// <returns></returns>
        public static long WriteSet(RedisKey key, List<RedisValue> values)
        {
            return GetDatabase().SetAdd(key, values.ToArray());
        }
        /// <summary>
        /// 写多个值到有序集合中，根据值的分数大小排序
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="score"></param>
        /// <returns></returns>
        public static long WriteSortedSet(RedisKey key, List<SortedSetEntry> sortedSetEntry)
        {
            return GetDatabase().SortedSetAdd(key, sortedSetEntry.ToArray());
        }
        /// <summary>
        /// 删除集合中的多个值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="values"></param>
        /// <returns></returns>
        public static long DeleteSetValues(RedisKey key, List<RedisValue> values)
        {
            return GetDatabase().SetRemove(key, values.ToArray());
        }
        public static long DeleteSortedSetValues(RedisKey key, List<RedisValue> values)
        {
            return GetDatabase().SortedSetRemove(key, values.ToArray());
        }
        /// <summary>
        /// 删除集合中的一个值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="values"></param>
        /// <returns></returns>
        public static bool DeleteSetValues(RedisKey key, RedisValue value)
        {
            return GetDatabase().SetRemove(key, value);
        }
        public static bool DeleteSortedSetValues(RedisKey key, RedisValue value)
        {
            return GetDatabase().SortedSetRemove(key, value);
        }



        //List
        /// <summary>
        /// 列表的头部插入一个值。
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>返回插入后的列表长度</returns>
        /// </summary>
        public static long ListLeftPush(RedisKey key, RedisValue value)
        {
            return GetDatabase().ListLeftPush(key, value);
        }
        /// <summary>
        /// 从列表的头部取出一个值。
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>取出的值</returns>
        /// </summary>
        public static RedisValue ListLeftPop(RedisKey key, RedisValue value)
        {
            return GetDatabase().ListLeftPop(key);
        }

        /// <summary>
        /// 列表的尾部插入一个值。
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>返回插入后的列表长度</returns>
        /// </summary>
        public static long ListRightPush(RedisKey key, RedisValue value)
        {
            return GetDatabase().ListRightPush(key, value);
        }
        /// <summary>
        /// 从列表的尾部取出一个值。
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns>取出的值</returns>
        /// </summary>
        public static RedisValue ListRightPop(RedisKey key, RedisValue value)
        {
            return GetDatabase().ListRightPop(key);
        }
        
       
    }
}
